
import uuid
from typing import Dict, List, Any, Optional
import logging
import datetime
import threading
import time
from threading import Timer

class ChatHistoryManager:
    def __init__(self):
        # 使用字典存储对话历史，键为conversation_id，值为对话记录列表
        self.chat_histories: Dict[str, List[Dict[str, Any]]] = {}
        # 最大历史记录数
        self.max_history_length = 20
        # 线程锁确保并发安全
        self._lock = threading.RLock()
        # 自动清理配置
        self.auto_cleanup_interval = 3600  # 1小时清理一次
        self.max_conversation_age_hours = 168  # 7天后过期
        # 启动自动清理定时器
        self._start_auto_cleanup()

    def create_new_conversation(self) -> str:
        """创建新的对话，返回conversation_id"""
        conversation_id = str(uuid.uuid4())
        with self._lock:
            self.chat_histories[conversation_id] = []
        logging.info(f"[对话管理] 新建对话，conversation_id: {conversation_id}，初始历史消息数量: 0")
        return conversation_id

    def add_message(self, conversation_id: str, role: str, content: str, additional_info: Optional[Dict[str, Any]] = None) -> None:
        """添加消息到对话历史"""
        with self._lock:
            if conversation_id not in self.chat_histories:
                self.chat_histories[conversation_id] = []

            message = {
                "role": role,  # 'user' 或 'assistant'
                "content": content,
                "timestamp": self._get_current_timestamp()
            }

            if additional_info:
                message.update(additional_info)

            self.chat_histories[conversation_id].append(message)

            # 限制历史记录长度
            if len(self.chat_histories[conversation_id]) > self.max_history_length:
                self.chat_histories[conversation_id].pop(0)

    def get_history(self, conversation_id: str) -> List[Dict[str, Any]]:
        """获取对话历史"""
        with self._lock:
            # 返回副本，避免外部修改影响内部数据
            return list(self.chat_histories.get(conversation_id, []))

    def _get_current_timestamp(self) -> str:
        """获取当前时间戳"""
        return datetime.datetime.now().isoformat()

    def cleanup_old_conversations(self, max_age_hours: Optional[int] = None) -> int:
        """清理超过指定小时数的对话历史"""
        if max_age_hours is None:
            max_age_hours = self.max_conversation_age_hours
            
        current_time = datetime.datetime.now()
        expired_ids = []
        
        with self._lock:
            for conv_id, history in list(self.chat_histories.items()):
                if not history:
                    expired_ids.append(conv_id)
                    continue
                try:
                    # 获取最后一条消息的时间
                    last_message_time = datetime.datetime.fromisoformat(history[-1]['timestamp'])
                    if (current_time - last_message_time).total_seconds() > max_age_hours * 3600:
                        expired_ids.append(conv_id)
                except (ValueError, KeyError) as e:
                    # 时间戳格式错误或缺少timestamp字段，标记为过期
                    logging.warning(f"[对话管理] 对话 {conv_id} 时间戳解析失败: {str(e)}，标记为过期")
                    expired_ids.append(conv_id)
            
            # 删除过期对话
            for conv_id in expired_ids:
                del self.chat_histories[conv_id]
                
        if expired_ids:
            logging.info(f"[对话管理] 清理了 {len(expired_ids)} 个过期对话")
        return len(expired_ids)


    def _start_auto_cleanup(self) -> None:
        """启动自动清理定时器"""
        def auto_cleanup_task():
            try:
                cleaned_count = self.cleanup_old_conversations()
                if cleaned_count > 0:
                    logging.info(f"[对话管理] 自动清理完成，清理了 {cleaned_count} 个过期对话")
                # 内存使用情况统计
                total_conversations = len(self.chat_histories)
                total_messages = sum(len(history) for history in self.chat_histories.values())
                logging.info(f"[对话管理] 当前活跃对话: {total_conversations}，总消息数: {total_messages}")
            except Exception as e:
                logging.error(f"[对话管理] 自动清理出错: {str(e)}")
            finally:
                # 重新安排下次清理
                self._schedule_next_cleanup()
        
        # 安排首次清理
        self._schedule_next_cleanup()
    
    def _schedule_next_cleanup(self) -> None:
        """安排下次自动清理"""
        def cleanup_wrapper():
            try:
                cleaned_count = self.cleanup_old_conversations()
                if cleaned_count > 0:
                    logging.info(f"[对话管理] 自动清理完成，清理了 {cleaned_count} 个过期对话")
                # 内存使用情况统计
                with self._lock:
                    total_conversations = len(self.chat_histories)
                    total_messages = sum(len(history) for history in self.chat_histories.values())
                logging.debug(f"[对话管理] 当前活跃对话: {total_conversations}，总消息数: {total_messages}")
            except Exception as e:
                logging.error(f"[对话管理] 自动清理出错: {str(e)}")
            finally:
                # 重新安排下次清理
                timer = Timer(self.auto_cleanup_interval, cleanup_wrapper)
                timer.daemon = True
                timer.start()
        
        # 启动定时器
        timer = Timer(self.auto_cleanup_interval, cleanup_wrapper)
        timer.daemon = True  # 设为守护线程，主程序退出时自动结束
        timer.start()
    
    def get_stats(self) -> Dict[str, Any]:
        """获取对话管理统计信息"""
        with self._lock:
            total_conversations = len(self.chat_histories)
            total_messages = sum(len(history) for history in self.chat_histories.values())
            
            # 计算平均消息数
            avg_messages = total_messages / total_conversations if total_conversations > 0 else 0
            
            return {
                "total_conversations": total_conversations,
                "total_messages": total_messages,
                "average_messages_per_conversation": round(avg_messages, 2),
                "max_history_length": self.max_history_length,
                "auto_cleanup_interval_seconds": self.auto_cleanup_interval,
                "max_conversation_age_hours": self.max_conversation_age_hours
            }
    
    def force_cleanup_all(self) -> int:
        """强制清理所有对话历史（谨慎使用）"""
        with self._lock:
            count = len(self.chat_histories)
            self.chat_histories.clear()
            logging.warning(f"[对话管理] 强制清理了所有 {count} 个对话")
            return count


# 创建全局单例
chat_history_manager = ChatHistoryManager()